﻿using DeZhen.Core.Framework.Entity;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace DeZhen.Core.Framework.Platform
{
    public static class RegisterPlatform
    {
        public static void InitializeRegisterService(this IServiceCollection services)
        {
            services.RegisterConsul();
            services.RegisterServiceByLifeTime(ServiceLifetime.Singleton);
            services.RegisterServiceByLifeTime(ServiceLifetime.Scoped);
            services.RegisterServiceByLifeTime(ServiceLifetime.Transient);
        }
        private static void RegisterConsul(this IServiceCollection services)
        {
            Type consulType = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll", SearchOption.TopDirectoryOnly)
              .Select(Assembly.LoadFrom)
              .SelectMany(a => a.GetTypes())
              .Where(t => t.FullName == "DeZhen.Core.Consul.Service.RegisterPlatform").FirstOrDefault();
            if (consulType != null)
            {
                Object consul = Activator.CreateInstance(consulType);
                MethodInfo method = consulType.GetMethod("InitializeRegisterConsulConfig");
                method.Invoke(consul, null);
            }
        }
        private static void RegisterServiceByLifeTime(this IServiceCollection services, ServiceLifetime serviceLifeTime)
        {
            var types = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll", SearchOption.TopDirectoryOnly)
                .Select(Assembly.LoadFrom)
                .SelectMany(a => a.GetTypes())
                .Where(t => t.GetCustomAttributes(typeof(ServiceAttribute), false).Length > 0 && t.GetCustomAttribute<ServiceAttribute>().LifeTime == serviceLifeTime && t.IsClass && !t.IsAbstract).ToList();

            types.ForEach(t =>
            {
                Type i = t.GetInterfaces().ToList().FirstOrDefault();
                switch (serviceLifeTime)
                {
                    case ServiceLifetime.Singleton: services.AddSingleton(i ?? t, t); break;
                    case ServiceLifetime.Scoped: services.AddScoped(i ?? t, t); break;
                    case ServiceLifetime.Transient: services.AddTransient(i ?? t, t); break;
                    default: services.AddTransient(i ?? t, t); break;
                };
            });
        }
    }
}
